//GameScene.h
//Created 19/02/14
//Created By Daniel Bowler
//
//The scene for our game case game. 

#pragma once

#include "AbstractScene.h"

//Number of point/spot lights. 
#define NUM_LIGHTS 50

//MSAA State for this scene? Comment to turn it off, uncomment to turn on.
#define GAME_SCENE_ENABLE_MSAA

//How many orbs in the scene? 
#define GAME_SCENE_INITIAL_NUM_ORBS 2

//How many houses in the scene
#define GAME_SCENE_NUM_HOUSES 4

//Forward declare the advanced models we use. 
class SkyDome;
class Terrain;

//Forward declare roo's world specific models and HUD
class Player;
class InstancedOrbs;
class House;
class QuestGiver;
class GameHUD;

class GameScene : public AbstractScene
{
public: 
	//Constructor and Destructor. Constructor will be used
	//to init the classes variables (and any pointers to NULL) but leave
	//dynamic allocation to the InitDynamicData() - unless absolutly required
	GameScene();
	~GameScene();

	//Override the init and dealloc functions
	void OpenScene();
	void CloseScene();
	
	//Called when we transition back to this scene from a demo scene - reset lights
	//and the like
	void OnSceneReset();

	//Override the mouse input functions
	void OnMouseDown(WPARAM btnState, int x, int y, UINT originalMessage);
	void OnMouseUp(WPARAM btnState, int x, int y, UINT originalMessage);
	void OnMouseMove(WPARAM btnState, int x, int y);

	//Override OnResize function. 
	void OnResize();

	//Override the render and update functions
	void UpdateWithDelta(float delta);
	void RenderScene();

private:
	//Scene States.
	enum SceneState 
	{ 
		SCENE_STATE_DRAW_SCENE,						//Draws as usual
		SCENE_STATE_DRAW_Z_PRE_PASS_DEPTH_BUFFER,   //Draws depth buffer as full screen quad.
		SCENE_STATE_DRAW_CS_MAX_Z_DEPTH_BUFFER,     //(Optional) Draws tile max z Buffer.
		SCENE_STATE_DRAW_CS_LLSEB_GREYSCALE,		//Visualise how many lights affect a tile. 
		SCENE_STATE_DRAW_CS_LLSEB_COLOUR,           //As above, but with more colour.
		SCENE_STATE_DRAW_CS_LLSEBT_GREYSCALE,       //Transparant tiles - greyscale.
		SCENE_STATE_DRAW_CS_LLSEBT_COLOUR,			//Transparant tiles - colour
		SCENE_STATE_DRAW_SSAO_VIEW_NORMALS,			//Draws view space normal tex (SSAO)
		SCENE_STATE_DRAW_SSAO_VIEW_DEPTHS,			//Draws view space depths (SSAO)
		SCENE_STATE_DRAW_SSAO_MAP,					//Draws SSAOMap.   
		SCENE_STATE_DRAW_SHADOW_DEPTH,				//Draws shadow map DSV 
		SCENE_STATE_DRAW_TERRAIN_REFLECTION,        //Draws terrain water reflection map
		SCENE_STATE_DRAW_TERRAIN_REFACTION          //Draws terrain water refaction map
	};

private:
	//Scene State - what to render?
	SceneState sceneState;

	//Should render lights?
	bool shouldRenderLights;
	//Use free camera
	bool useFreeCamera;

private:
	//Direc light
	DirectionalLight dLight;

private:
	//2D rendering
	FontSheet* font;
	SpriteBatch* spriteBatch;
	ID3D11ShaderResourceView* tex2D;

private:
	//Terrain.
	Terrain* terrain;
	//SkyDome
	SkyDome* skyDome;

private:
	//Collectables: Orbs
	InstancedOrbs* orb;

private:
	//House exterior models - we will teleport to differnt
	//scenes
	House* houseModels;

private:
	//Player model that we use in the game - a nice kangaroo
	Player* playerModel;

	//NPC model for the game (gives the player quests)
	QuestGiver* NPCModel;

	// The heads up display for the 
	GameHUD* HUD;

private:
	//Loads terrain
	void LoadTerrain();

	//Load the our game models. 
	void LoadModels();

	//Loads house model and creates instances. 
	void LoadHouseModel();

	//Load and init our player
	void LoadPlayer();

	//Load and init our NPC model
	void LoadNPC();

	// Load our HUD fonts and 2D images
	void LoadHUD();

	//Loads the collectables
	void LoadCollectables();

	//Load the SkyDome (and set)
	void LoadSkyDome();

	//Load 2D font stuff
	void LoadFontData();

	//Load initial lighting data (point, spot)
	void InitLighting();
	//Init Direc light
	void InitDirecLight();
	//Inits hemispherial ambient light
	void InitHemisphericalAmbientLight();
};